iT邦幫忙

2024 iThome 鐵人賽

DAY 17
0
Mobile Development

Flutter基礎入門系列 第 17

【Day 17】嘗試解決問題:Future 與 non-Future類別間的存取

  • 分享至 

  • xImage
  •  

昨天發現當一個函式回傳的物件類別是Future時,無法將它assign至一個非Future的物件之中,使得目前資料庫中的內容無法成功顯示於應用程式之中。今日就來嘗試解決這個問題吧!


在做了一點資料查詢後,找到有人也有類似的疑問,以下為擷取StackOverflow問題:How to use a Future in a non-Future class的回答。

方法一:使用.then()
https://ithelp.ithome.com.tw/upload/images/20241001/20169446AlFBmfZuZ9.png

雖然這很容易,但筆者的程式中想要獲得value值也會遇到Future與non-Future類別的問題,因此這個方法應該不太容易實行

方法二:使用類別FutureBuilder
關於此類別的官方說明請點此
https://ithelp.ithome.com.tw/upload/images/20241001/20169446yoFQDUMi3N.png

這是最多人推薦的方式,且下方有個好心人為原po寫了以下這個使用範例:

import 'package:flutter/services.dart' show rootBundle;
import 'dart:convert';
import 'package:flutter/material.dart';

class UserModel {
  final id;
  final firstName;

  UserModel({
    this.firstName,
    this.id,
  });

  factory UserModel.fromJson(Map<String, dynamic> json) {
    return UserModel(
      id: json['id'],
      firstName: json['firstName'],
    );
  }
}

Future<List<UserModel>?> decupagemJson() async {
  var resposta = await rootBundle.loadString('assets/myData.json');
  List dadosExtraidos = json.decode(resposta);
  return dadosExtraidos.map((user) => UserModel.fromJson(user)).toList();
}

class YourClassName extends StatefulWidget {
  @override
  _YourClassNameState createState() => _YourClassNameState();
}

class _YourClassNameState extends State<YourClassName> {
  late Future<List<UserModel>?> myList;
  @override
  void initState() {
    myList = decupagemJson();
    // TODO: implement initState
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    //to check if value returned from Future is correct

    return Scaffold(
      appBar: AppBar(
        title: Text(''),
      ),
      body: Center(
        child:
        FutureBuilder<List<UserModel>?>(
          builder: (con, snap) {
            if (snap.hasData) {
              return ListView.builder(
                itemCount: snap.data!.length,
                itemBuilder: (context, index) {
                  return Container(
                    color: Colors.red,
                    height: 90,
                    child: Column(
                      children: [
                        Text('id :${snap.data![index].id}'),
                        SizedBox(
                          height: 3,
                        ),
                        Text('name :${snap.data![index].firstName}'),
                        SizedBox(
                          height: 10,
                        ),
                      ],
                    ),
                  );
                },
              );
            } else {
              return CircularProgressIndicator();
            }
          },
          future: myList,
        ),
      ),
    );
  }
}

接下來筆者將會嘗試將這個方法implement至自己的程式之中,中間需要一點時間try and error,因此最後的程式碼將會於之後再更新上來。


上一篇
【Day 16】為資料建立widget
下一篇
【Day 18】sqflite無法開啟電腦資料庫使用:用sqflite_ffi代替吧!
系列文
Flutter基礎入門30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言